package com.lbt.mybatis.plus.extend.interceptor;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.lbt.mybatis.plus.extend.bean.MPEBoundSql;
import com.lbt.mybatis.plus.extend.bean.QueryField;
import com.lbt.mybatis.plus.extend.bean.QueryFieldObjectItemParent;
import com.lbt.mybatis.plus.extend.util.MybatisPlusExtendSqlUtils;
import net.sf.jsqlparser.JSQLParserException;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.util.List;
import java.util.Optional;

/**
 * @author zhangjinyu
 * @since 2023-05-16
 */
public interface ExtendInnerInterceptor extends InnerInterceptor {

    default public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        Optional<QueryField> queryFieldOptional = MybatisPlusExtendSqlUtils.findQueryField(parameter);
        if (queryFieldOptional.isEmpty()) {
            return;
        }
        String buildSql = boundSql.getSql();
        List<QueryFieldObjectItemParent> queryFieldObjectItemParents = MybatisPlusExtendSqlUtils.createQueryObjectItems(queryFieldOptional.get());
        MPEBoundSql mpeBoundSql = MPEBoundSql.of(ms.getConfiguration(), boundSql);
        try {
            MybatisPlusExtendSqlUtils.buildMpeBoundSql(mpeBoundSql, buildSql, queryFieldObjectItemParents);
        } catch (JSQLParserException e) {
            throw new MybatisPlusException("mpe 查询sql构建异常", e);
        }
        PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
        mpBoundSql.sql(mpeBoundSql.getSql());
        List<ParameterMapping> mappings = mpBoundSql.parameterMappings();
        mappings.addAll(mpeBoundSql.getMappings());
        mpBoundSql.parameterMappings(mappings);
    }
}
